package com.ochnas.volunteersignup.domain;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Transient;

@Entity
public class Position implements Serializable {
	@Transient
	private static Comparator<TimeSlot> sortByAscendingTime = new Comparator<TimeSlot>() {

		@Override
		public int compare(TimeSlot t1, TimeSlot t2) {
			Time t1StartTime = t1.getStartTime();
			Time t2StartTimie = t2.getStartTime();
			if (t1StartTime.getHourOfDay() > t2StartTimie.getHourOfDay()) {
				return 1;
			} else if (t1StartTime.getHourOfDay() < t2StartTimie.getHourOfDay()) {
				return -1;
			} else {
				if (t1StartTime.getMinutes() > t2StartTimie.getMinutes()) {
					return 1;
				} else if (t1StartTime.getMinutes() < t2StartTimie.getMinutes()) {
					return -1;
				}
			}
			return 1;
		}
		
	};

	@Id @GeneratedValue
	private Long id;
	private String name;
	private String description;
	private int requiredNumberOfVolunteers;
	
	@ManyToOne
	private Event event;
	
	@OneToMany(cascade = CascadeType.ALL, mappedBy = "position")
	private List<TimeSlot> timeSlots = new ArrayList<TimeSlot>();
	
	/**
	 * No-argument constructor.
	 */
	public Position() {
		super();
	}

	/**
	 * Position-defined constructor.
	 * @param name
	 * @param description
	 * @param requiredNumberOfVolunteers
	 */
	public Position(String name, String description,
			int requiredNumberOfVolunteers) {
		super();
		this.name = name;
		this.description = description;
		this.requiredNumberOfVolunteers = requiredNumberOfVolunteers;
	}
	
	/**
	 * Method to add TimeSlot 
	 * @param timeSlot - TimeSlot
	 * @return
	 */
	public TimeSlot addTimeSlot(TimeSlot timeSlot) {
		timeSlot.setPosition(this);
		timeSlots.add(timeSlot);
		return timeSlot;
	}
	
	
	/**
	 * Method to remove a time slot from the list of TimeSlots.
	 * @param timeSlots - TimeSlot
	 * @return boolean - true, if removal is successful; false, otherwise.
	 */
	public boolean removeTimeSlot(TimeSlot timeSlot) {
		return timeSlots.remove(timeSlot);
	}
	
	/**
	 * Method to sort the time slots in the list of TimeSlot
	 * @return
	 */
	public List<TimeSlot> getTimeSlots() {
		TimeSlot[] tsArray = timeSlots.toArray(new TimeSlot[0]);
		Arrays.sort(tsArray, sortByAscendingTime);
		return Collections.unmodifiableList(Arrays.asList(tsArray));
	}
	
	
	/**
	 * Method to return Position id
	 * @return Long
	 */
	public Long getId() {
		return id;
	}
	
	/**
	 * Method to set Position id
	 * @param id Long
	 */
	public void setId(Long id) {
		this.id = id;
	}
	
	/**
	 * Method to return Position name
	 * @return String
	 */
	public String getName() {
		return name;
	}
	
	/**
	 * Method to set Position name
	 * @param name
	 */
	public void setName(String name) {
		this.name = name;
	}
	
	/**
	 * Method to return the description of the position
	 * @return String
	 */
	public String getDescription() {
		return description;
	}
	
	/**
	 * Method to set the description of the postion
	 * @param description
	 */
	public void setDescription(String description) {
		this.description = description;
	}
	
	/**
	 * Method to return the required number of volunteers
	 *   for the position
	 * @return int
	 */
	public int getRequiredNumberOfVolunteers() {
		return requiredNumberOfVolunteers;
	}
	
	/**
	 * Method to set the required number of volunteers
	 *   for the position
	 * @param requiredNumberOfVolunteers
	 */
	public void setRequiredNumberOfVolunteers(int requiredNumberOfVolunteers) {
		this.requiredNumberOfVolunteers = requiredNumberOfVolunteers;
	}

	public Event getEvent() {
		return event;
	}

	public void setEvent(Event event) {
		this.event = event;
	}

	@Override
	public String toString() {
		StringBuffer strBuff = new StringBuffer("Position[id=");
		strBuff.append(id);
		strBuff.append("]{name=");
		strBuff.append(name);
		strBuff.append(",description=");
		strBuff.append(description);
		strBuff.append(",requiredNumberOfVolunteers=");
		strBuff.append(requiredNumberOfVolunteers);
		strBuff.append(",eventId=");
		if (event == null) {
			strBuff.append(event);
		} else {
			strBuff.append(event.getId());
		}
		strBuff.append("}");
		return strBuff.toString();
	}

	public void setTimeSlots(List<TimeSlot> timeSlots) {
		this.timeSlots = timeSlots;
	}
	
}
